/*
 * Copyright (c) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.hos_ahmedadeltito.photoeditorsdk.slice;

import com.hos_ahmedadeltito.photoeditorsdk.*;
import com.hos_ahmedadeltito.photoeditorsdk.provider.EmojiClickedListener;
import com.hos_ahmedadeltito.photoeditorsdk.provider.ImageClickedListener;
import com.hos_ahmedadeltito.photoeditorsdk.provider.PagerProvider;
import com.hos_ahmedadeltito.photoeditorsdk.utils.FontUtil;


import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.ability.DataAbilityHelper;
import ohos.aafwk.ability.DataAbilityRemoteException;
import ohos.aafwk.content.Intent;
import ohos.agp.components.*;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.text.Font;
import ohos.agp.utils.Color;
import ohos.agp.utils.LayoutAlignment;
import ohos.agp.utils.Point;
import ohos.agp.window.dialog.PopupDialog;
import ohos.agp.window.service.Display;
import ohos.agp.window.service.DisplayManager;
import ohos.app.Context;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
import ohos.media.image.ImageSource;
import ohos.media.image.PixelMap;
import ohos.media.photokit.metadata.AVStorage;
import ohos.multimodalinput.event.TouchEvent;
import ohos.utils.IntervalTimer;
import ohos.utils.net.Uri;

import java.io.FileDescriptor;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;

public class PhotoEditorAbilitySlice extends AbilitySlice implements Component.ClickedListener, OnPhotoEditorSDKListener {
    private Context context;
    private DependentLayout parentImageRelativeLayout;
    private ListContainer drawingViewColorPickerRecyclerView;
    private Text doneDrawingTextView, eraseDrawingTextView;
    private DependentLayout undoTextLayout;
    private Font emojiFont, newFont;
    private DependentLayout topShadowRelativeLayout;
    private DependentLayout bottomShadowRelativeLayout;
    private ArrayList<Integer> colorPickerColors;
    private Color colorCodeTextView = Color.GRAY;
    private PhotoEditorSDK photoEditorSDK;


    private int data[] = {
        ResourceTable.Color_black,
        ResourceTable.Color_blue_color_picker,
        ResourceTable.Color_brown_color_picker,
        ResourceTable.Color_green_color_picker,
        ResourceTable.Color_orange_color_picker,
        ResourceTable.Color_red_color_picker,
        ResourceTable.Color_red_orange_color_picker,
        ResourceTable.Color_sky_blue_color_picker,
        ResourceTable.Color_violet_color_picker,
        ResourceTable.Color_white,
        ResourceTable.Color_yellow_color_picker,
        ResourceTable.Color_yellow_green_color_picker
    };

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_activity_photo_editor);
        context = getContext();


        //接收值
        String uri = intent.getStringParam("key");

        Uri parse = Uri.parse(uri);
        PixelMap pixelMap = getPixelMapByUri(parse);


        emojiFont = FontUtil.createFontBuild(this, "emojione-android.ttf");
        newFont = FontUtil.createFontBuild(this, "Eventtus-Icons.ttf");

        BrushDrawingView brushDrawingView = (BrushDrawingView) findComponentById(ResourceTable.Id_drawing_view);

        drawingViewColorPickerRecyclerView = (ListContainer) findComponentById(ResourceTable.Id_drawing_view_color_picker_recycler_view);
        parentImageRelativeLayout = (DependentLayout) findComponentById(ResourceTable.Id_parent_image_rl);
        Text closeTextView = (Text) findComponentById(ResourceTable.Id_close_tv);
        closeTextView.setClickedListener(this);
        Text addTextView = (Text) findComponentById(ResourceTable.Id_add_text_tv);
        addTextView.setClickedListener(this);
        Text addPencil = (Text) findComponentById(ResourceTable.Id_add_pencil_tv);
        addPencil.setClickedListener(this);
        DependentLayout deleteRelativeLayout = (DependentLayout) findComponentById(ResourceTable.Id_delete_rl);
        Text deleteTextView = (Text) findComponentById(ResourceTable.Id_delete_tv);
        Text addImageEmojiTextView = (Text) findComponentById(ResourceTable.Id_add_image_emoji_tv);
        addImageEmojiTextView.setClickedListener(this);
        DependentLayout clear = (DependentLayout) findComponentById(ResourceTable.Id_clear);
        clear.setClickedListener(this);
        undoTextLayout = (DependentLayout) findComponentById(ResourceTable.Id_undo_dl);
        undoTextLayout.setClickedListener(this);
        doneDrawingTextView = (Text) findComponentById(ResourceTable.Id_done_drawing_tv);
        doneDrawingTextView.setClickedListener(this);
        eraseDrawingTextView = (Text) findComponentById(ResourceTable.Id_erase_drawing_tv);
        eraseDrawingTextView.setClickedListener(this);
        DependentLayout clearAllTextLayout = (DependentLayout) findComponentById(ResourceTable.Id_clean_all);
        clearAllTextLayout.setClickedListener(this);
        Text goToNextTextView = (Text) findComponentById(ResourceTable.Id_go_to_next_screen_tv);
        goToNextTextView.setClickedListener(this);
        Image photoEditImageView = (Image) findComponentById(ResourceTable.Id_photo_edit_iv);

        photoEditImageView.setPixelMap(pixelMap);
        photoEditImageView.setScaleMode(Image.ScaleMode.CLIP_CENTER);
        ShapeElement shapeElement = new ShapeElement(this, ResourceTable.Graphic_above_shadow);
        topShadowRelativeLayout = (DependentLayout) findComponentById(ResourceTable.Id_top_parent_rl);
        bottomShadowRelativeLayout = (DependentLayout) findComponentById(ResourceTable.Id_bottom_parent_rl);
        bottomShadowRelativeLayout.setBackground(shapeElement);
        topShadowRelativeLayout.setBackground(shapeElement);
        Text saveTextView = (Text) findComponentById(ResourceTable.Id_save_tv);
        Text clearAllTextView = (Text) findComponentById(ResourceTable.Id_clear_all_tv);
        Text undoTextView = (Text) findComponentById(ResourceTable.Id_undo_tv);

        doneDrawingTextView.setTouchEventListener(new Component.TouchEventListener() {
            @Override
            public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
                return true;
            }
        });

        closeTextView.setFont(newFont);
        addTextView.setFont(newFont);
        addPencil.setFont(newFont);
        addImageEmojiTextView.setFont(newFont);
        saveTextView.setFont(newFont);
        undoTextView.setFont(newFont);
        clearAllTextView.setFont(newFont);
        goToNextTextView.setFont(newFont);
        deleteTextView.setFont(newFont);

        photoEditorSDK = new PhotoEditorSDK.PhotoEditorSDKBuilder(getContext())
            .parentView(parentImageRelativeLayout) // add parent image view
            .childView(photoEditImageView) // add the desired image view
            .deleteView(deleteRelativeLayout) // add the deleted view that will appear during the movement of the views
            .brushDrawingView(brushDrawingView, photoEditImageView.getPixelMap()) // add the brush drawing view that is responsible for drawing on the image view
            .buildPhotoEditorSDK(); // build photo editor sdk
        photoEditorSDK.setOnPhotoEditorSDKListener(this);

        colorPickerColors = new ArrayList<>();
//        //todo 鸿蒙无  getResources()
        colorPickerColors.add(getColor(ResourceTable.Color_black));
        colorPickerColors.add(getColor(ResourceTable.Color_blue_color_picker));
        colorPickerColors.add(getColor(ResourceTable.Color_brown_color_picker));
        colorPickerColors.add(getColor(ResourceTable.Color_green_color_picker));
        colorPickerColors.add(getColor(ResourceTable.Color_orange_color_picker));
        colorPickerColors.add(getColor(ResourceTable.Color_red_color_picker));
        colorPickerColors.add(getColor(ResourceTable.Color_red_orange_color_picker));
        colorPickerColors.add(getColor(ResourceTable.Color_sky_blue_color_picker));
        colorPickerColors.add(getColor(ResourceTable.Color_violet_color_picker));
        colorPickerColors.add(getColor(ResourceTable.Color_white));
        colorPickerColors.add(getColor(ResourceTable.Color_yellow_color_picker));
        colorPickerColors.add(getColor(ResourceTable.Color_yellow_green_color_picker));
    }


    private PixelMap getPixelMapByUri(Uri uri) {
        DataAbilityHelper helper = DataAbilityHelper.creator(getContext());
        PixelMap pixelMap = null;
        try {
            String lastPath = uri.getLastPath();
            if (lastPath.contains(":")) {
                String[] strs = lastPath.split(":");
                lastPath = strs[strs.length - 1];

            }
            Uri uri1 = Uri.appendEncodedPathToUri(AVStorage.Images.Media.EXTERNAL_DATA_ABILITY_URI, "" + lastPath);

            FileDescriptor filedesc = helper.openFile(uri1, "r");

            ImageSource.SourceOptions sourceOptions = new ImageSource.SourceOptions();
            sourceOptions.formatHint = "image/png";
            ImageSource cacheImageSource = ImageSource.create(filedesc, sourceOptions);

            ImageSource.DecodingOptions decodingOptions = new ImageSource.DecodingOptions();
            decodingOptions.editable = true;
            pixelMap = cacheImageSource.createPixelmap(decodingOptions);

        } catch (DataAbilityRemoteException | FileNotFoundException e) {
            e.printStackTrace();
        }
        return pixelMap;
    }


    private void popuShow() {

        //获取屏幕宽度
        Optional<Display> display = DisplayManager.getInstance().getDefaultDisplay(this.getContext());
        Point pt = new Point();
        display.get().getSize(pt);
        Component parse = LayoutScatter.getInstance(getContext()).parse(ResourceTable.Layout_layout_icon_popupdialog, null, false);
        PopupDialog dialog = new PopupDialog(getContext(), parse, DependentLayout.LayoutConfig.MATCH_PARENT, DependentLayout.LayoutConfig.MATCH_PARENT);
        initPopup(parse, dialog);
        dialog.show();
    }

    private void initPopup(Component mPopupComponent, PopupDialog dialog) {
        dialog.setCustomComponent(mPopupComponent);
        dialog.setTransparent(true);

        dialog.setBackColor(new Color(Color.getIntColor("#33ffffff")));
        Text back = (Text) mPopupComponent.findComponentById(ResourceTable.Id_back);
        back.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                dialog.destroy();
            }
        });

        PageSlider pager = (PageSlider) mPopupComponent.findComponentById(ResourceTable.Id_image_emoji_view_pager);
        pager.setProvider(new PagerProvider(initPageSliderViewData(dialog)));
        pager.setCurrentPage(0);
        pager.setReboundEffect(true);
        pager.setCentralScrollMode(true);
    }

    private ArrayList<Component> initPageSliderViewData(PopupDialog dialog) {
        ArrayList<Component> pages = new ArrayList<>();
        pages.add(new ImageFraction(this, new ImageClickedListener() {
            @Override
            public void onClick(Component component, PixelMap pixelMap) {
                photoEditorSDK.addImage(pixelMap);
                dialog.destroy();
            }
        }).createView());
        pages.add(new EmojiFraction(this, emojiFont, new EmojiClickedListener() {
            @Override
            public void onClick(Component component, String text, Font font) {
                photoEditorSDK.addEmoji(text, font);
                dialog.destroy();
            }
        }).createView());
        return pages;
    }

    private boolean stringIsNotEmpty(String string) {
        if (string != null && !string.equals("null")) {
            if (!string.trim().equals("")) {
                return true;
            }
        }
        return false;
    }


    private void addText(String text, Color colorCodeTextView) {
        photoEditorSDK.addText(text, colorCodeTextView);
    }

    private void clearAllViews() {
        photoEditorSDK.clearAllViews();
    }

    private void undoViews() {
        photoEditorSDK.viewUndo();
    }

    private void eraseDrawing() {
        photoEditorSDK.brushEraser();
    }


    private void openAddTextPopupWindow(String text, Color colorCode) {
        colorCodeTextView = colorCode;
        LayoutScatter inflater = LayoutScatter.getInstance(getContext());
        Component addTextPopupWindowRootView = inflater.getInstance(getContext()).parse(ResourceTable.Layout_add_text_popup_windows, null, false);
        TextField addTextEditText = (TextField) addTextPopupWindowRootView.findComponentById(ResourceTable.Id_add_text_edit_text);
        addTextEditText.setTextColor(colorCodeTextView);
        addTextEditText.getFocusable();
        addTextEditText.setFocusable(Text.AUTO_CURSOR_POSITION);
        Text addTextDoneTextView = (Text) addTextPopupWindowRootView.findComponentById(ResourceTable.Id_add_text_done_tv);
        ListContainer addTextColorPickerRecyclerView = (ListContainer) addTextPopupWindowRootView.findComponentById(ResourceTable.Id_add_text_color_picker_recycler_view);
        List<ColorBean> list = new ArrayList();
        for (int i = 0; i < data.length; i++) {
            list.add(new ColorBean(data[i]));
        }
        ColorPickerAdapter sampleItemProvider = new ColorPickerAdapter(this, list, this);
        addTextColorPickerRecyclerView.setItemProvider(sampleItemProvider);
        addTextColorPickerRecyclerView.setItemClickedListener(new ListContainer.ItemClickedListener() {
            @Override
            public void onItemClicked(ListContainer listContainer, Component component, int i, long l) {
                ColorBean item = (ColorBean) listContainer.getItemProvider().getItem(i);
                colorCodeTextView = new Color(context.getColor(item.getColor()));
                addTextEditText.setTextColor(colorCodeTextView);
            }
        });
        addTextColorPickerRecyclerView.setTouchEventListener(new Component.TouchEventListener() {
            @Override
            public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
                return true;
            }
        });

        if (stringIsNotEmpty(text)) {
            addTextEditText.setText(text);
        }

        PopupDialog pop = new PopupDialog(this, addTextPopupWindowRootView, DependentLayout.LayoutConfig.MATCH_PARENT, DependentLayout.LayoutConfig.MATCH_PARENT);
        pop.setCustomComponent(addTextPopupWindowRootView);
        pop.setTransparent(true);
        pop.showOnCertainPosition(LayoutAlignment.TOP, 0, 0);
        addTextDoneTextView.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                addText(addTextEditText.getText(), colorCodeTextView);
                pop.destroy();
            }
        });
    }

    private void updateView(int visibility) {
        topShadowRelativeLayout.setVisibility(visibility);
        bottomShadowRelativeLayout.setVisibility(visibility);

    }

    //点击画笔 传入true
    private void updateBrushDrawingView(boolean brushDrawingMode) {
        photoEditorSDK.setBrushDrawingMode(brushDrawingMode);
        if (brushDrawingMode) {
            updateView(Component.HIDE);
            drawingViewColorPickerRecyclerView.setVisibility(Component.VISIBLE);
            doneDrawingTextView.setVisibility(Component.VISIBLE);
            eraseDrawingTextView.setVisibility(Component.VISIBLE);

            List<ColorBean> list = new ArrayList();
            for (int i = 0; i < data.length; i++) {
                list.add(new ColorBean(data[i]));
            }
            ColorPickerAdapter sampleItemProvider = new ColorPickerAdapter(this, list, this);//ColorPickerAdapter参数 ： PhotoEditorActivity.this, colorPickerColors

            drawingViewColorPickerRecyclerView.setItemProvider(sampleItemProvider);
            drawingViewColorPickerRecyclerView.setTouchEventListener(new Component.TouchEventListener() {
                @Override
                public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
                    return true;
                }
            });
            drawingViewColorPickerRecyclerView.setItemClickedListener(new ListContainer.ItemClickedListener() {
                @Override
                public void onItemClicked(ListContainer listContainer, Component component, int i, long l) {
                    ColorBean item = (ColorBean) listContainer.getItemProvider().getItem(i);
                    Color color1 = new Color(context.getColor(item.getColor()));

                    photoEditorSDK.setBrushColor(color1);
                }
            });
        } else {
            updateView(Component.VISIBLE);
            drawingViewColorPickerRecyclerView.setVisibility(Component.HIDE);
            doneDrawingTextView.setVisibility(Component.HIDE);
            eraseDrawingTextView.setVisibility(Component.HIDE);
        }
    }


    private void returnBackWithSavedImage() {
        updateView(Component.HIDE);
        DependentLayout.LayoutConfig layoutParams = new DependentLayout.LayoutConfig(
            DependentLayout.LayoutConfig.MATCH_CONTENT, DependentLayout.LayoutConfig.MATCH_CONTENT);

        layoutParams.addRule(DependentLayout.LayoutConfig.CENTER_IN_PARENT, DependentLayout.LayoutConfig.TRUE);
        parentImageRelativeLayout.setLayoutConfig(layoutParams);
        new IntervalTimer(1000, 500) {
            @Override
            public void onInterval(long remain) {
                // This method will be called at the 3000th millisecond and repeatedly called every 3000 milliseconds.
            }

            @Override
            public void onFinish() {
                // This method will be called at the 60000th millisecond.
                String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
                String imageName = "IMG_" + timeStamp + ".jpg";
                Intent returnIntent = new Intent();
                returnIntent.setParam("imagePath", photoEditorSDK.saveImage("PhotoEditorSDK", imageName));
                setResult(returnIntent);
                terminate();
            }
        }.schedule();

    }

    @Override
    public void onClick(Component v) {
        if (v.getId() == ResourceTable.Id_close_tv) {
            onBackPressed();
        } else if (v.getId() == ResourceTable.Id_add_image_emoji_tv) {//弹出表情列表
            popuShow();
        } else if (v.getId() == ResourceTable.Id_add_text_tv) {//添加text
            openAddTextPopupWindow("", colorCodeTextView);
        } else if (v.getId() == ResourceTable.Id_add_pencil_tv) {//画笔
            updateBrushDrawingView(true);
        } else if (v.getId() == ResourceTable.Id_done_drawing_tv) {//关闭当前界面
            updateBrushDrawingView(false);
        } else if (v.getId() == ResourceTable.Id_clear) {//保存图片
            returnBackWithSavedImage();
        } else if (v.getId() == ResourceTable.Id_clean_all) {//清除所有涂鸦包括所有编辑输入内容
            clearAllViews();
        } else if (v.getId() == ResourceTable.Id_undo_dl) {//返回上一步
            undoViews();
        } else if (v.getId() == ResourceTable.Id_erase_drawing_tv) {//橡皮擦
            eraseDrawing();
        } else if (v.getId() == ResourceTable.Id_go_to_next_screen_tv) {//保存
            returnBackWithSavedImage();
        }
    }


    @Override
    public void onEditTextChangeListener(String text, int colorCode) {

        openAddTextPopupWindow(text, colorCodeTextView);//参数colorCode
    }

    private static final HiLogLabel BRUSH_DRAWING = new HiLogLabel(HiLog.LOG_APP, 0x00201, "BRUSH_DRAWING");
    private static final HiLogLabel EMOJI = new HiLogLabel(HiLog.LOG_APP, 0x00201, "EMOJI");
    private static final HiLogLabel IMAGE = new HiLogLabel(HiLog.LOG_APP, 0x00201, "IMAGE");
    private static final HiLogLabel TEXT = new HiLogLabel(HiLog.LOG_APP, 0x00201, "TEXT");


    @Override
    public void onAddViewListener(ViewType viewType, int numberOfAddedViews) {
        if (numberOfAddedViews > 0) {
            undoTextLayout.setVisibility(Component.VISIBLE);
        }
        switch (viewType) {
            case BRUSH_DRAWING:
                HiLog.info(BRUSH_DRAWING, "onAddViewListener");
                break;
            case EMOJI:
                HiLog.info(EMOJI, "onAddViewListener");
                break;
            case IMAGE:
                HiLog.info(IMAGE, "onAddViewListener");
                break;
            case TEXT:
                HiLog.info(TEXT, "onAddViewListener");
                break;
        }
    }

    @Override
    public void onRemoveViewListener(int numberOfAddedViews) {
        LogUtils.showLog("onRemoveViewListener");
        if (numberOfAddedViews == 0) {
            undoTextLayout.setVisibility(Component.HIDE);
        }
    }

    private static final HiLogLabel BRUSH_DRAWING1 = new HiLogLabel(HiLog.LOG_APP, 0x00101, "BRUSH_DRAWING");
    private static final HiLogLabel EMOJI1 = new HiLogLabel(HiLog.LOG_APP, 0x00101, "EMOJI");
    private static final HiLogLabel IMAGE1 = new HiLogLabel(HiLog.LOG_APP, 0x00101, "IMAGE");
    private static final HiLogLabel TEXT1 = new HiLogLabel(HiLog.LOG_APP, 0x00101, "TEXT");

    @Override
    public void onStartViewChangeListener(ViewType viewType) {
        switch (viewType) {
            case BRUSH_DRAWING:
                HiLog.info(BRUSH_DRAWING1, "onStartViewChangeListener");
                break;
            case EMOJI:
                HiLog.info(EMOJI1, "onStartViewChangeListener");
                break;
            case IMAGE:
                HiLog.info(IMAGE1, "onStartViewChangeListener");
                break;
            case TEXT:
                HiLog.info(TEXT1, "onStartViewChangeListener");
                break;
        }
    }

    private static final HiLogLabel BRUSH_DRAWING2 = new HiLogLabel(HiLog.LOG_APP, 0x00101, "BRUSH_DRAWING");
    private static final HiLogLabel EMOJI2 = new HiLogLabel(HiLog.LOG_APP, 0x00202, "EMOJI");
    private static final HiLogLabel IMAGE2 = new HiLogLabel(HiLog.LOG_APP, 0x00202, "IMAGE");
    private static final HiLogLabel TEXT2 = new HiLogLabel(HiLog.LOG_APP, 0x0023, "TEXT");

    @Override
    public void onStopViewChangeListener(ViewType viewType) {
        switch (viewType) {
            case BRUSH_DRAWING:
                HiLog.info(BRUSH_DRAWING2, "onStopViewChangeListener");
                break;
            case EMOJI:
                HiLog.info(EMOJI2, "onStopViewChangeListener");
                break;
            case IMAGE:
                HiLog.info(IMAGE2, "onStopViewChangeListener");
                break;
            case TEXT:
                HiLog.info(TEXT2, "onStopViewChangeListener");
                break;
        }
    }

    @Override
    public void onActive() {
        super.onActive();
    }

    @Override
    public void onForeground(Intent intent) {
        super.onForeground(intent);
    }


}
